package com.hyper_yang._05_juc.chap04;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

public class NotSafeDemo {

    public static void main(String[] args) {
        //notSafeList();
        //notSafeSet();
        notSafeMap();
    }

    //List集合安全性
    private static void notSafeList() {
        //List<String> list = new ArrayList<>(); //不安全  java.util.ConcurrentModificationException 底层数组   10     1.5倍    有序 可重复
        //List<String> list = new Vector<>(); //安全 方法都增加synchronized    10   2倍    有序 可重复
        //List<String> list = Collections.synchronizedList(new ArrayList<>()); //安全 - 调用ArrayList集合方法时增加同步代码块。synchronized (mutex) {list.add(index, element);}

        //安全  采用读写分离的思想解决安全问题。将旧集合复制一份，长度+1，往新集合写，不影响旧集合读。写后切换引用指针。
        //存在问题：需要占用2倍的内存空间。需要容忍暂时数据不一致。
        List<String> list = new CopyOnWriteArrayList<>();
        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0, 8));
                System.out.println(list);
            }, String.valueOf(i)).start();
        }
    }

    private static void notSafeSet() {
        //java.util.ConcurrentModificationException
        //Set<String> set = new HashSet<>(); // 底层HashMap  数据存在map的key上，所以不能重复。map的值就是默认Object对象。无序。不安全。
        //Set<String> set = Collections.synchronizedSet(new HashSet<>()); //安全  public boolean add(E e) {synchronized (mutex) {return c.add(e);}}
        Set<String> set = new CopyOnWriteArraySet<>(); //特点同CopyOnWriteArrayList

        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                set.add(UUID.randomUUID().toString().substring(0, 8));
                System.out.println(set);
            }, String.valueOf(i)).start();
        }
    }

    private static void notSafeMap() {

        //java.util.ConcurrentModificationException
        //Map<String, String> map = new HashMap<>(); // k-v  不安全  16   0.75   2倍    数组 + 链表/红黑树
        //Map<String, String> map = Collections.synchronizedMap(new HashMap<>()); //安全
        Map<String, String> map = new ConcurrentHashMap<>();  //安全   采用分段锁保证安全。

        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                map.put(String.valueOf(Thread.currentThread().getName()), UUID.randomUUID().toString().substring(0, 8));
                System.out.println(map);
            }, String.valueOf(i)).start();
        }
    }

}